/** 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package it.free.i.virtual.machine.hal.devicealias.port;

import it.free.i.virtual.machine.hal.LinkingOperationException;
import it.free.i.virtual.machine.hal.devicealias.command.DeviceAliasPortCommandVerb;
import it.free.i.virtual.machine.hal.devicealias.command.DeviceAliasPortMessage;
import it.free.i.virtual.machine.hal.devicealias.command.DeviceAliasPortMessageImpl;
import it.free.i.virtual.machine.hal.devicealias.command.DeviceAliasPortMessagePayload;

import java.util.List;
import java.util.Properties;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ReflectionException;

/**
 * Application subdomains bridge
 * Default device alias port implementation for a device alias port, as this aggregate different features
 * from a class extension and DeviceAliasPort interface implementation.
 * @author stefano
 */
public abstract class DeviceAliasPortSupportImpl extends NotificationBroadcasterSupport implements DeviceAliasPort {
	
	public DeviceAliasPortSupportImpl() {
	}

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract String getName();

	/**   
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract DeviceAliasPortCommandVerb getMode();

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract Object invoke(List<Object> input);

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract void setMode(DeviceAliasPortCommandVerb mode);

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract void link(Properties virtualDeviceConfiguration) throws LinkingOperationException;

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract void unlink() throws LinkingOperationException;
	
	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract void handleNotification(Notification notification, Object handback);

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract void run();

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract Object getAttribute(String attribute)
			throws AttributeNotFoundException, MBeanException,
			ReflectionException;

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract AttributeList getAttributes(String[] attributes);

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract MBeanInfo getMBeanInfo() ;

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract Object invoke(String actionName, Object[] params, String[] signature)
			throws MBeanException, ReflectionException;

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract void setAttribute(Attribute attribute)
			throws AttributeNotFoundException, InvalidAttributeValueException,
			MBeanException, ReflectionException;

	/** 
	 * @see it.free.i.virtual.machine.hal.devicealias.port.DeviceAliasPort
	 */
	public abstract AttributeList setAttributes(AttributeList attributes);
	
	/**
	 * Build the notification object with custom params for this application subsystem domain
	 * @param type is the type of notification sent
	 * @param message is a message associated with this notification
	 * @param sequenceNumber is this message sequence number
	 * @param payload is the data bundle to send back
	 * @return a notification ready-to-send object
	 */
	public Notification buildNotification(DeviceAliasPortCommandVerb type, 
										  String message, 
										  long sequenceNumber, 
										  DeviceAliasPortMessagePayload payload){
		
		DeviceAliasPortMessage deviceAliasPortMessage = new DeviceAliasPortMessageImpl();
		
		Notification notification = new Notification(type.toString(),
                									 message,
                									 sequenceNumber,
                									 System.currentTimeMillis(),
                									 this.getName() + " " + message);
		
		deviceAliasPortMessage.setPayload(payload);
		
		notification.setUserData(deviceAliasPortMessage);
		
		return notification;
	}

}
